---
id: debug
title: Common Problems
sidebar_label: Common Problem Solutions
---

Spec-compliant OAuth 2.0 and OpenID Connect is hard. Let's take a look how to
resolve certain issues.

## First Aid

There are three things you can do to quickly debug any issue:

1. Check the logs. ORY Hydra has extensive logging and you will find the issue
   most likely in the logs. Here is an example log line for a client that
   requested a redirect URL that did not match the whitelisted redirect URLS:
   `time="2018-08-07T16:01:16Z" level=error msg="An error occurred" description="The request is missing a required parameter, includes an invalid parameter value, includes a parameter more than once, or is otherwise malformed" error=invalid_request hint="The \"redirect_uri\" parameter does not match any of the OAuth 2.0 Client's pre-registered redirect urls."`
2. Check the URL because of two reasons:
   1. ORY Hydra sends `error_hint`, `error`, `error_description`, `error_debug`
      in the URL. You will find the cause of the error most likely in there.
   2. You are maybe in the wrong URL. Make sure the host and port and path is
      correct. This happens often, especially when you're just starting out and
      experimenting
3. Set environment variable `OAUTH2_EXPOSE_INTERNAL_ERRORS=true`. Do not do this
   in production, it is possible, though unlikely, that important data leaks
   with this. If set to true, ORY Hydra will set the `error_debug` query
   parameter if debug information is available.
4. If you're just starting out and experimenting your docker set up does not
   work at all:
   1. Stop all containers
   2. Remove them (unless you have something important running)
   3. Retry. **This can help a lot if you are new to this!**

## OpenID Connect ID Token missing

If you expect an OAuth 2.0 ID Token but are not receiving one, this can have
multiple reasons:

1. You are using the `client_credentials` grant which can not return an ID
   token.
2. You forgot to request the `openid` scope when calling
   `/oauth2/auth?response_type=code` (Authorize Code Flow - correct would be
   `/oauth2/auth?response_type=code&scope=openid`) or the `id_token` response
   type when calling `/oauth2/auth?response_type=token` (Implicit/Hybrid flow -
   correct would be `/oauth2/auth?response_type=token+id_token&scope=openid` or
   any other combination such as `response_type=id_token`,
   `response_type=token+code+id_token`).
3. You forgot to include `nonce` when calling `/oauth2/auth?response_type=id_token`
   or any combination of `id_token` (`token+id_token`, `token+code+id_token` etc.)
   `nonce` is a value sent by the client application and included as a claim in 
   the returned `id_token`. The `nonce` claim can then be verified by the client 
   application to mitigate any replay attacks. Optional for Authoize Code Flow,
   but mandatory for Implicit/Hybrid flow. Correct request would be - 
   `/oauth2/auth?response_type=id_token?nonce=some-value`.
   You can read more about `nonce` here [OpenId Connect Core](https://openid.net/specs/openid-connect-core-1_0.html#NonceNotes).
4. Your consent app did not send `granted_scope: ["openid"]` or when accepting
   the consent request.
5. The OAuth 2.0 Client making the request is not allowed to request the scope
   `openid`.

## OAuth 2.0 Refresh Token is missing

If you expect an OAuth 2.0 Refresh Token but are not receiving one, this can
have multiple reasons:

1. You are using an implicit or hybrid flow. These flows never return a refresh
   token!
2. You are using the `client_credentials` grant which can not return a refresh
   token.
3. You forgot to request the `offline` or `offline_access` scope when calling
   `/oauth2/auth`.
4. You consent app did not send `granted_scope: ["offline"]` or
   `granted_scope: ["offline_access"]` when accepting the consent request.
5. The OAuth 2.0 Client making the request is not allowed to grant type
   `refresh_token`.

## OAuth 2.0 Authorize Code Flow fails

The most likely cause is misconfiguration, summarized in the next sections.

## Refresh Token Flow fails

Refresh tokens can become invalid if abuse is detected, but coding issues may
also trigger this scenario, for example if a client makes multiple requests.

Some common examples:

1.  Replay of authorization code grant.
2.  Replay of refresh token grant.

### Wrong or misconfigured OAuth 2.0 Client

You are using the wrong OAuth 2.0 Client or the OAuth 2.0 Client has a broken
configuration. To check that you're using the right client, run:

```
hydra clients get --endpoint http://ory-hydra <the-client-id>
```

The result shows you the whole client (excluding its secret). Check that the
values are correct. Example:

```
{
        "client_id": "my-client",
        "grant_types": [
                "authorization_code"
        ],
        "jwks": {},
        "redirect_uris": [
                "http://127.0.0.1:5556/callback"
        ],
        "response_types": [
                "code"
        ],
        "scope": "openid offline",
        "subject_type": "pairwise",
        "token_endpoint_auth_method": "client_secret_basic",
        "userinfo_signed_response_alg": "none"
}
```

### Redirect URL is not whitelisted

A likely cause of your request failing is that you are using the wrong redirect
URL. Assuming your OAuth 2.0 URL looks like
`http://ory-hydra/oauth2/auth?client_id=my-client&...&redirect_uri=http://my-url/callback`

The redirect URL `http://my-url/callback` must be whitelisted in your client
configuration. The URLs must match **exactly**. URL `http://my-url/callback` and
`http://my-url/callback?foo=bar` are different URLs!

To see the whitelisted redirect_uris, check the client:

```
hydra clients get --endpoint http://ory-hydra <the-client-id>

{
        // ...
        "redirect_uris": [
                "http://127.0.0.1:5556/callback"
        ],
        // ...
}
```

Here you see that `http://my-url/callback` is not in the list, which is why the
request fails.

### oauth2/token endpoint fails for jwks based client

When trying to get an access token for a client registered with
`"token_endpoint_auth_method": "private_key_jwt"` it is possible that the
provided jwt has expired.

The response body that is sent to the client is like below

```
{
    "error": "error",
    "error_description": "The error is unrecognizable Token is expired"
}
```

The debug error messages is not provided to avoid divulging more information to
a malicious client.

However if you need more information in repsonse (for debugging) , you can
enable the following environment variables in hydra server :

```

OAUTH2_EXPOSE_INTERNAL_ERRORS=true;
OAUTH2_INCLUDE_LEGACY_ERROR_FIELDS=true
```

This configuration are documented
[here](https://www.ory.sh/hydra/docs/reference/configuration/).

Now you will be able to see the error_debug field in the response like below :

```
{
    "error": "error",
    "error_description": "The error is unrecognizable",
    "status_code": 500,
    "error_debug": "Token is expired"
}
```
